/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Exercicio3;

import java.util.HashMap;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Pedro-Note
 */
public class ThreadCalculaIntegral extends Thread {

    Stack<HashMap<String, Double>> pilha;
    Stack<Double> pilhaResultado;
    public static final double EPS = 0.00000000001;

    ThreadCalculaIntegral(Stack<HashMap<String, Double>> pilha, Stack<Double> pilhaResultado) {
        this.pilha = pilha;
        this.pilhaResultado = pilhaResultado;
    }

    @Override
    public void run() {
        while (pilha.size() > 0) {
            HashMap<String, Double> hash = desempilha();
            Double left, right, fleft, fright, lrarea;
            left = (double) hash.get("left");
            right = (double) hash.get("right");
            fleft = (double) hash.get("fleft");
            fright = (double) hash.get("fright");
            lrarea = (double) hash.get("lrarea");

            double mid = (left + right) / 2;
            double fmid = Math.floor(mid);
            double larea = (fleft + fmid) * (mid - left) / 2;
            double rarea = (fmid + fright) * (right - mid) / 2;
            if (Math.abs((larea + rarea) - lrarea) > EPS) {

                HashMap<String,Double> integral = new HashMap<String,Double>();
                integral.put("left", left);
                integral.put("right", mid);
                integral.put("fleft", fleft);
                integral.put("fright", fmid);
                integral.put("lrarea", larea);
                empilha(integral);

                integral = new HashMap<String,Double>();
                integral.put("left", mid);
                integral.put("right", right);
                integral.put("fleft", fmid);
                integral.put("fright", fright);
                integral.put("lrarea", rarea);
                empilha(integral);

            } else {


                empilhaResultado(rarea + larea);
                }
            }
        }
    

    public synchronized void empilha(HashMap<String,Double> integral)
    {
        while(pilha.capacity() == pilha.size()){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(ThreadCalculaIntegral.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        this.pilha.push(integral);

        notifyAll();

    }

     public synchronized void empilhaResultado(Double integral)
    {
        while(pilhaResultado.capacity() == pilhaResultado.size()){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(ThreadCalculaIntegral.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        if (this.pilhaResultado.size()==0)
          this.pilhaResultado.push(integral);
        else
           this.pilhaResultado.push(desempilhaResultado() + integral);
        
        notifyAll();

    }

      public synchronized HashMap desempilha()
    {
        while(pilha.size()==0){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(ThreadCalculaIntegral.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        HashMap retorna = this.pilha.pop();

        notifyAll();
        return retorna;
    }

     public synchronized Double desempilhaResultado()
    {
        while(pilhaResultado.size()==0){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(ThreadCalculaIntegral.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        Double retorna = this.pilhaResultado.pop();

        notifyAll();
        return retorna;
    }
}
